<?php

namespace App\Repositories;

use Exception;
use Carbon\Carbon;
use App\Models\User;
use App\Models\Project;
use App\Models\Identification;
use Illuminate\Support\Facades\Hash;
use App\Exceptions\GeneralException;

/**
 * 用户模块Repository
 *
 * Date: 21/03/2018
 * @author George
 * @package App\Repositories
 */
class UserRepository extends BaseRepository
{
	/**
	 * 定义模型类
	 *
	 * Date: 21/03/2018
	 * @author George
	 * @return mixed|string
	 */
	public function model()
	{
		return User::class;
	}

	/**
	 * 根据公司获取用户信息
	 *
	 * Date: 12/04/2018
	 * @author George
	 * @param $company
	 * @param $name
	 * @param $mobile
	 * @param $status
	 * @param $project_id
	 * @param $position_id
	 * @param $certificate
	 * @return \Illuminate\Database\Eloquent\Builder
	 */
	public function getByCompany($company, $name, $mobile, $status, $project_id, $position_id, $certificate)
	{
		$this->query = User::query();
		$this->query->where('company_id', '=', $company);

		$this->query->with(['projects:projects.id,name', 'company:id,title']);

		if ($name) {
			$this->query->where('name', 'like', "%{$name}%");
		}

		if ($mobile) {
			$this->query->where('mobile', 'like', "%{$name}%");
		}

		if ($status) {
			$this->query->where('status', '=', $status);
		}

		if ($project_id) {
			$this->query->where('project_id', '=', $project_id);
		}

		if ($position_id) {
			$this->query->where('position_id', '=', $position_id);
		}

		if ($certificate != null) {
			if ($certificate === 'true') {
				$this->query->whereNotNull('certificate');
			} else {
				$this->query->whereNull('certificate');
			}
		}

		return $this->query;
	}

	/**
	 * 获取用户权限
	 *
	 * Date: 25/03/2018
	 * @author George
	 * @param User $user
	 * @return \Illuminate\Support\Collection
	 */
	public function getPermissions(User $user)
	{
		return $user->position()->with('permissions')->pluck('code');
	}

	/**
	 * 修改用户密码
	 *
	 * Date: 21/03/2018
	 * @author George
	 * @param $oldPassword
	 * @param $newPassword
	 * @param User $user
	 * @return bool
	 * @throws \Throwable
	 */
	public function modifyPassword($oldPassword, $newPassword, User $user): bool
	{
		$result = $this->verifyPassword($user, $oldPassword);

		if ($result) {
			$user->password = $newPassword;
			return $user->saveOrFail();
		}

		return false;
	}

	/**
	 * 验证给定项目和日期范围是否存在记录
	 *
	 * Date: 25/03/2018
	 * @author George
	 * @param int $project
	 * @param Carbon $start
	 * @param Carbon $end
	 * @return bool
	 */
	public function memberOfProjectByDateRange(int $project, Carbon $start, Carbon $end)
	{
		$count = $this->projects()->where('projects.id', $project)->where('type', '<>', 'main')
			->whereBetween('start', [$start, $end])
			->orWhereBetween('end', [$start, $end])
			->orWhere('start', '<', $start)
			->where('end', '>', $end)->count();
		return $count > 0;
	}

	/**
	 * 获取用户的主项目信息
	 *
	 * Date: 25/03/2018
	 * @author George
	 * @param $user
	 * @return Project|null
	 */
	public function mainProject($user)
	{
		$project = null;

		if (is_integer($user)) {
			$project = $this->projects()->where('users.id', $user)->where('type', '=', 'main')->first();
		} elseif ($user instanceof User) {
			$project = $user->projects()->where('type', '=', 'main')->first();
		}
		return $project;
	}

	/**
	 * 修改头像
	 *
	 * Date: 21/03/2018
	 * @author George
	 * @param string $path
	 * @param User $user
	 * @return bool
	 * @throws \Throwable
	 */
	public function modifyAvatar(string $path, User $user): bool
	{
		$user->avatar = $path;
		return $user->saveOrFail();
	}

	/**
	 * 验证用户密码
	 *
	 * Date: 21/03/2018
	 * @author George
	 * @param User $user
	 * @param $plain
	 * @return bool
	 */
	public function verifyPassword(User $user, $plain)
	{
		return Hash::check($plain, $user->getAuthPassword());
	}

	/**
	 * 更新用户身份信息
	 *
	 * Date: 11/04/2018
	 * @author George
	 * @param array $attributes
	 * @return \Illuminate\Database\Eloquent\Model
	 * @throws GeneralException
	 */
	public function modifyIdentification(array $attributes)
	{
		try {
			return Identification::updateOrCreate($attributes, array_values($attributes));
		} catch (Exception $exception) {
			throw new GeneralException('更新用户身份信息失败');
		}
	}

	protected function serialization(array $attributes)
	{
		// TODO: Implement serialization() method.
	}
}
